package cn.stylefeng.guns.modular.business.frequency.ordersub.service.impl;

import cn.hutool.core.lang.Validator;
import cn.stylefeng.guns.core.context.login.LoginContextHolder;
import cn.stylefeng.guns.core.enums.CoreExceptionEnum;
import cn.stylefeng.guns.core.exception.CustomException;
import cn.stylefeng.guns.core.pojo.base.entity.BaseEntity;
import cn.stylefeng.guns.core.pojo.page.AndaPageResult;
import cn.stylefeng.guns.core.pojo.response.ResponseData;
import cn.stylefeng.guns.modular.business.custom.enums.FinanceTypeEnum;
import cn.stylefeng.guns.modular.business.custom.enums.OrderStatusEnum;
import cn.stylefeng.guns.modular.business.custom.enums.SettlementTypeEnum;
import cn.stylefeng.guns.modular.business.custom.enums.TakeCarTypeEnum;
import cn.stylefeng.guns.modular.business.frequency.cmcompany.mapper.CmCompanyMapper;
import cn.stylefeng.guns.modular.business.frequency.cmcompanyorder.entity.CmCompanyOrder;
import cn.stylefeng.guns.modular.business.frequency.cmcompanyorder.mapper.CmCompanyOrderMapper;
import cn.stylefeng.guns.modular.business.frequency.cmdriver.mapper.CmDriverMapper;
import cn.stylefeng.guns.modular.business.frequency.cmlinkman.mapper.CmLinkmanMapper;
import cn.stylefeng.guns.modular.business.frequency.finance.entity.Finance;
import cn.stylefeng.guns.modular.business.frequency.finance.mapper.FinanceMapper;
import cn.stylefeng.guns.modular.business.frequency.financedetail.entity.FinanceDetail;
import cn.stylefeng.guns.modular.business.frequency.financedetail.mapper.FinanceDetailMapper;
import cn.stylefeng.guns.modular.business.frequency.ordermodifydetail.entity.OrderModifyDetail;
import cn.stylefeng.guns.modular.business.frequency.ordermodifydetail.mapper.OrderModifyDetailMapper;
import cn.stylefeng.guns.modular.business.frequency.orderstatuschange.entity.OrderStatusChange;
import cn.stylefeng.guns.modular.business.frequency.orderstatuschange.service.OrderStatusChangeService;
import cn.stylefeng.guns.modular.business.frequency.ordersub.entity.OrderSub;
import cn.stylefeng.guns.modular.business.frequency.ordersub.mapper.OrderSubMapper;
import cn.stylefeng.guns.modular.business.frequency.ordersub.model.param.OrderDTO;
import cn.stylefeng.guns.modular.business.frequency.ordersub.model.result.PkgTake;
import cn.stylefeng.guns.modular.business.frequency.ordersub.model.result.TakeOrderVO;
import cn.stylefeng.guns.modular.business.frequency.ordersub.service.OrderSubService;
import cn.stylefeng.guns.modular.business.frequency.ordersub.service.TakeCarService;
import cn.stylefeng.guns.modular.business.frequency.ordertake.entity.OrderTake;
import cn.stylefeng.guns.modular.business.frequency.ordertake.mapper.OrderTakeMapper;
import cn.stylefeng.guns.modular.business.frequency.statistics.PkgOrderTake;
import cn.stylefeng.guns.modular.business.util.BusinessUtil;
import cn.stylefeng.guns.modular.util.BaseUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author jzy
 * @Date 2021/2/5 0005
 **/
@Service
@Transactional(rollbackFor = Exception.class)
public class TakeCarServiceImpl extends ServiceImpl<OrderSubMapper, OrderSub> implements TakeCarService {

    @Resource
    private OrderSubService orderSubService;
    @Resource
    private OrderStatusChangeService orderStatusChangeService;

    @Resource
    private OrderTakeMapper orderTakeMapper;
    @Resource
    private OrderSubMapper orderSubV2Mapper;
    @Resource
    private FinanceMapper financeMapper;
    @Resource
    private FinanceDetailMapper financeDetailMapper;
    @Resource
    private CmDriverMapper driverMapper;
    @Resource
    private BusinessUtil businessUtil;
    @Resource
    private CmCompanyOrderMapper companyOrderMapper;
    @Resource
    private CmLinkmanMapper linkmanMapper;
    @Resource
    private CmCompanyMapper companyMapper;
    @Resource
    private OrderModifyDetailMapper orderModifyDetailMapper;

    public PkgTake getTakeCarDetail(Long orderId) {
        PkgTake take = orderTakeMapper.getPkgTakeDetail(orderId);
        //OrderTake ot = orderTakeMapper.selectOne(new QueryWrapper<OrderTake>().lambda().eq(OrderTake::getOrderId, orderId));
        return take;
    }

    public boolean checkAssignUpdate(OrderTake orderTake, StringBuilder errorMsg) {
        if (orderTake == null || orderTake.getOrderId() == null) {
            errorMsg.append("参数错误，订单ID不能为空");
            return false;
        }
        if (StringUtils.isNotBlank(orderTake.getDriverPhone()) && !Validator.isMobile(orderTake.getDriverPhone())) {
            errorMsg.append("司机电话格式不正确！");
            return false;
        }
        // 只有待验车订单可以修改指派信息
        /*int status = orderSubMapper.getStatusById(orderTake.getOrderId());
        if (status != OrderStatusEnum.WAIT_TAKE.status && status != OrderStatusEnum.WAIT_ASSIGN_TAKE_DRIVER.status) {
            errorMsg.setErrorMsg("订单当前状态不可修改送车车司机信息！");
            return false;
        }*/
        // 已结算的提车费不可修改提车信息
        Finance finance = financeMapper.selectOne(new QueryWrapper<Finance>().lambda().eq(Finance::getOrderId, orderTake.getOrderId()));
        if (finance != null && finance.getTakeHas() != null && finance.getTakeHas().compareTo(BigDecimal.ZERO) > 0) {
            errorMsg.append("该订单的送车费已经结算，不可修改！");
            return false;
        }
        return true;
    }


    public void updateAssign(OrderTake orderTake) {
        OrderTake origin = orderTakeMapper.selectOne(new QueryWrapper<OrderTake>().lambda()
                .eq(OrderTake::getOrderId, orderTake.getOrderId()));
        // 是否指派了司机信息
        if (BaseUtils.hasAssignDriver(orderTake.getDriverId(), orderTake.getDriverName(),
                orderTake.getDriverPhone(), orderTake.getDriverCardNumber(), orderTake.getLicensePlateNumber())) {
            // 指派了司机信息，更新指派时间和指派人
            if (origin.getAssignDriverUser() == null) {
                orderTake.setAssignDriverUser(LoginContextHolder.me().getSysLoginUserId());
            }
            if (origin.getAssignDriverTime() == null) {
                orderTake.setAssignDriverTime(new Date());
            }

            // 订单状态修改, 如果订单状态为待指派司机
            if (orderSubV2Mapper.getStatusById(orderTake.getOrderId()) == OrderStatusEnum.WAIT_ASSIGN_TAKE_DRIVER.status) {
                orderSubV2Mapper.updateStatusById(orderTake.getOrderId(), OrderStatusEnum.WAIT_TAKE.status, null);
            }
        } /*else {
            // 没有指派司机信息
            orderSubV2Mapper.updateStatusById(orderTake.getOrderId(), OrderStatusEnum.WAIT_ASSIGN_TAKE_DRIVER.status, null);
        }*/
        // 最后更新orderTake
        orderTakeMapper.update(orderTake, new QueryWrapper<OrderTake>().lambda().eq(OrderTake::getOrderId, orderTake.getOrderId()));
        // 企业通讯录订单信息更新
        CmCompanyOrder companyOrder = companyOrderMapper.getByOrderIdAndType(orderTake.getOrderId(), 4);
        if (companyOrder != null) {
            // 编辑
            companyOrder.setCompanyId(orderTake.getCompanyId());
            companyOrder.setLinkmanId(orderTake.getSettlementId());
            companyOrder.setDriverName(orderTake.getDriverName());
            companyOrder.setDriverPhone(orderTake.getDriverPhone());
            companyOrder.setFee(orderTake.getTakeCarFee());
            companyOrderMapper.updateById(companyOrder);
        }
        // 订单修改明细
        try {
            addOrderModifyDetail(orderTake, origin);
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }
    }

    private void addOrderModifyDetail(OrderTake now, OrderTake origin) {
        Long orderId = origin.getOrderId();
        Long userId = LoginContextHolder.me().getSysLoginUserId();
        List<OrderModifyDetail> list = new ArrayList<>();
        if (BaseUtils.neCompareTwo(now.getCompany(), origin.getCompany())) {
            list.add(new OrderModifyDetail(orderId, null,
                    "company", "送车公司名称", now.getCompany(), origin.getCompany(), userId));
        }
        if (BaseUtils.neCompareTwo(now.getSettlementName(), origin.getSettlementName())) {
            list.add(new OrderModifyDetail(orderId, null,
                    "settlement_name", "送车结算人", now.getSettlementName(), origin.getSettlementName(), userId));
        }
        if (BaseUtils.neCompareTwo(now.getSettlementPhone(), origin.getSettlementPhone())) {
            list.add(new OrderModifyDetail(orderId, null,
                    "settlement_phone", "送车结算人电话", now.getSettlementPhone(), origin.getSettlementPhone(), userId));
        }
        if (BaseUtils.neCompareTwo(now.getSettlementType(), origin.getSettlementType())) {
            list.add(new OrderModifyDetail(orderId, null, "settlement_type",
                    "送车结算方式", SettlementTypeEnum.getValue(now.getSettlementType()), SettlementTypeEnum.getValue(origin.getSettlementType()), userId));
        }
        if (BaseUtils.neCompareTwo(now.getDriverName(), origin.getDriverName())) {
            list.add(new OrderModifyDetail(orderId, null, "driver_name", "送车司机姓名",
                    now.getDriverName(), origin.getDriverName(), userId));
        }
        if (BaseUtils.neCompareTwo(now.getDriverPhone(), origin.getDriverPhone())) {
            list.add(new OrderModifyDetail(orderId, null, "driver_phone", "送车司机电话",
                    now.getDriverPhone(), origin.getDriverPhone(), userId));
        }
        if (BaseUtils.neCompareTwo(now.getLicensePlateNumber(), origin.getLicensePlateNumber())) {
            list.add(new OrderModifyDetail(orderId, null, "license_plate_number", "送车小板车牌",
                    now.getLicensePlateNumber(), origin.getLicensePlateNumber(), userId));
        }
        if (BaseUtils.neCompareTwo(now.getDriverCardNumber(), origin.getDriverCardNumber())) {
            list.add(new OrderModifyDetail(orderId, null, "driver_card_number", "送车司机身份证",
                    now.getDriverCardNumber(), origin.getDriverCardNumber(), userId));
        }
        // 结算人修改，需要修改财务相关表
        if (BaseUtils.neCompareTwo(now.getSettlementId(), origin.getSettlementId())) {
            financeMapper.updateTakeSettlementInfoByOrderId(origin.getOrderId(), now.getSettlementName(), now.getSettlementPhone());
            financeDetailMapper.updateSettlementUserInfo(origin.getOrderId(), FinanceTypeEnum.TAKE.type, now.getSettlementName(), now.getSettlementPhone(), now.getSettlementId());
        }
        if (!BaseUtils.compareDecimal(now.getTakeCarFee(), origin.getTakeCarFee())) {
            list.add(new OrderModifyDetail(orderId, null, "take_car_fee", "送车费",
                    now.getTakeCarFee().toString(), origin.getTakeCarFee().toString(), userId));
            try {
                orderSubService.modifyOrderFeeDetail(orderId, FinanceTypeEnum.TAKE.type, now.getTakeCarFee(), origin.getTakeCarFee(),
                        now.getSettlementId(), now.getSettlementName(), now.getSettlementPhone());
            } catch (Exception e) {
                throw new CustomException(e.getMessage());
            }
        }
        if (list.size() > 0) {
            for (OrderModifyDetail omd : list) {
                orderModifyDetailMapper.insert(omd);
            }
        }
    }


    public boolean checkAssignTake(StringBuilder errorMsg, OrderTake orderTake) {
        if (orderTake.getTakeOrderVOList() == null || orderTake.getTakeOrderVOList().size() < 1) {
            errorMsg.append("请至少选择一辆车指派送车");
            return false;
        }
        for (TakeOrderVO tov : orderTake.getTakeOrderVOList()) {
            OrderSub orderSub = orderSubV2Mapper.selectById(tov.getOrderId());
            if (orderSub.getTakeType() == TakeCarTypeEnum.ZI_SONG_WANG_DIAN.type) {
                errorMsg.append("请注意，" + orderSub.getCarName() + " 该车的送车方式为网点自提，不可指派！");
                return false;
            }
            if (orderSub.getStatus() != OrderStatusEnum.FINISHED_TRANSPORT.status) {
                errorMsg.append("请注意，" + orderSub.getCarName() + " 该车状态不可指派送车车！");
                return false;
            }
        }
   /*     if (orderTake.getDriverId()== null && StringUtils.isNotBlank(orderTake.getDriverName())
                && StringUtils.isNotBlank(orderTake.getDriverPhone())) {
            if (!Validator.isMobile(orderTake.getDriverPhone())) {
                errorMsg.append("司机电话格式错误！");
                return false;
            }
            if (driverMapper.countByPhone(orderTake.getDriverPhone(), null, businessUtil.getTenantId()) > 0) {
                errorMsg.append("已经存在" + orderTake.getDriverPhone() + "司机信息，请从提示中选择");
                return false;
            }
        }*/
        return true;
    }


    public void multiTake(OrderTake orderTake, Map<String, String> map) {
        // 指派了司机
        if (BaseUtils.hasAssignDriver(orderTake.getDriverId(), orderTake.getDriverName(), orderTake.getDriverPhone(),
                orderTake.getDriverCardNumber(), orderTake.getLicensePlateNumber())) {
            orderTake.setAssignDriverUser(LoginContextHolder.me().getSysLoginUserId());
            orderTake.setAssignDriverTime(new Date());
            if (orderTake.getDriverId() != null) {
                orderTake.setDriverId(orderTake.getDriverId());
            }
        }
        for (TakeOrderVO pov : orderTake.getTakeOrderVOList()) {
            orderTake.setOrderId(pov.getOrderId());
            orderTake.setTakeCarFee(pov.getCost());
            orderTake.setTenantId(businessUtil.getTenantId());
            orderTake.setId(null);
            // 指派信息保存
            orderTakeMapper.insert(orderTake);
            // 供应商订单
            // 子订单状态修改
            if (orderTake.getDriverId() == null) {
                // 没有选择司机
                //orderSubV2Mapper.updateStatusById(pov.getOrderId(), OrderStatusEnum.WAIT_ASSIGN_TAKE_DRIVER.status, null);
                orderSubV2Mapper.updateStatusById(pov.getOrderId(), OrderStatusEnum.WAIT_TAKE.status, null);
                // 供应商订单
            } else {
                orderSubV2Mapper.updateStatusById(pov.getOrderId(), OrderStatusEnum.WAIT_TAKE.status, null);
                // 供应商订单
            }
            OrderSub orderSub = orderSubV2Mapper.selectById(pov.getOrderId());
            orderStatusChangeService.saveOrderStatusChange(orderSub.getStatus(), OrderStatusEnum.WAIT_TAKE.status, orderSub.getId(), "送车");

            //添加送车提醒
            OrderSub orderSubBak = orderSubV2Mapper.selectById(pov.getOrderId());
            // 签收后 交付提醒
            businessUtil.addMessage(String.format("%s  %s待交付提醒", orderSubBak.getCarName(), orderSubBak.getVin()), "你有一个待交付订单，请及时处理", orderSubBak, 5);

            // 供应商订单保存
            // 通讯录订单数据插入
            addCompanyOrder(orderTake);
            // 财务提车数据插入
            if (pov.getCost() != null && pov.getCost().compareTo(BigDecimal.ZERO) > 0) {
                Finance finance = financeMapper.selectOne(new QueryWrapper<Finance>().lambda().eq(Finance::getOrderId, pov.getOrderId()));
                finance.setTake(pov.getCost());
                finance.setTakeHas(BigDecimal.ZERO);
                finance.setTakeUn(pov.getCost());
                finance.setTakeSettlementName(map.get("settlementName"));
                finance.setTakeSettlementPhone(map.get("settlementPhone"));
                finance.setTakeSettlementType(orderTake.getSettlementType());
                finance.setTenantId(businessUtil.getTenantId());
                financeMapper.update(finance, new QueryWrapper<Finance>().lambda().eq(Finance::getOrderId, pov.getOrderId()));
                // 财务明细插入
                FinanceDetail fd = new FinanceDetail();
                fd.setHasSettlement(BigDecimal.ZERO);
                fd.setNeedSettlement(pov.getCost());
                fd.setOrderId(pov.getOrderId());
                fd.setSettlementPhone(map.get("settlementPhone"));
                fd.setSettlementUser(map.get("settlementName"));
                fd.setUnSettlement(pov.getCost());
                if (map.get("settlementSiteId") != null) {
                    fd.setSettlementSiteId(Long.valueOf(map.get("settlementSiteId")));
                }
                fd.setType(FinanceTypeEnum.TAKE.type);
                fd.setSettlementUserId(Long.valueOf(map.get("settlementId")));
                fd.setSettlementType(orderTake.getSettlementType());
                fd.setTenantId(businessUtil.getTenantId());
                financeDetailMapper.insert(fd);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reMultiTake(Long orderId) {

        OrderStatusChange statusChange = orderStatusChangeService.getOne(new QueryWrapper<OrderStatusChange>().lambda()
                .eq(OrderStatusChange::getOrderId, orderId)
                .orderByDesc(BaseEntity::getCreateTime)
                .last("limit 1"));

        if (statusChange == null&&(statusChange!=null&&!"送车".equals(statusChange.getRemark()))) {
            throw new CustomException(CoreExceptionEnum.ORDER_CHANGE_STAGE_ERROR);
        }
        // 指派信息保存
        orderTakeMapper.delete(new QueryWrapper<OrderTake>().lambda().eq(OrderTake::getOrderId, orderId));

        orderSubV2Mapper.updateStatusById(orderId, statusChange.getBeforeChangeStatus(), null);
        companyOrderMapper.delete(new QueryWrapper<CmCompanyOrder>().lambda().eq(CmCompanyOrder::getOrderId, orderId));
        orderStatusChangeService.removeById(statusChange.getId());


    }

    private void addCompanyOrder(OrderTake orderTake) {
        CmCompanyOrder companyOrder = new CmCompanyOrder();

        companyOrder.setOrderId(orderTake.getOrderId());
        companyOrder.setType(4);
        companyOrder.setFee(orderTake.getTakeCarFee());
        companyOrder.setCompanyId(orderTake.getCompanyId());
        companyOrder.setLinkmanId(orderTake.getSettlementId());
        companyOrder.setAssignUser(LoginContextHolder.me().getSysLoginUserId());
        companyOrder.setAssignTime(new Date());
        companyOrder.setDriverName(orderTake.getDriverName());
        companyOrder.setDriverPhone(orderTake.getDriverPhone());
        companyOrder.setTenantId(businessUtil.getTenantId());
        companyOrderMapper.insert(companyOrder);
        // 最后一次接单时间更新
        linkmanMapper.updateLastTransportTime(orderTake.getSettlementId());
        companyMapper.updateLastTransportTime(orderTake.getCompanyId());
    }

    public List<PkgOrderTake> getWaitTakeExcludeList(OrderDTO orderDTO) {
        return orderTakeMapper.getWaitTakeExcludeList(orderDTO, businessUtil.getTenantId());
    }

    public ResponseData getWaitTakeList(Page<Object> defaultPage, OrderDTO orderDTO) {
        Page<PkgOrderTake> list = orderTakeMapper.getWaitTakeList(defaultPage, orderDTO);
        return ResponseData.andaSuccess(new AndaPageResult<>().AndaPageResult(list, orderDTO));

    }
}
